Kubernetes 存储的设计与基本架构
分享者:顾文俊,某互联网公司金融行业架构师。2008年南京邮电大学电路与系统专业研究生毕业,12+年职业生涯主要从事IT基础设施、云计算、容器、大数据、AI、金融科技相关领域的解决方案工作。
1、容器平台存储的基本知识
存储作为容器平台重要的组成部分,保证着容器数据的安全,在整个系统中具有举足轻重的作用,是整个设计的重中之重。
容器中数据的存储是临时性的,当容器消失的时候,数据也会随之消失,后来就有了持久化存储的研究;在Kubernetes平台上,Pod中同时多个容器运行,常常需要这些容器共享数据存储,来保证数据的安全性。Kubernetes抽象出Volume对象来解决存储方面的问题。Docker也有Volume的概念,但对它只有少量且松散的管理。在Docker中,Volume是磁盘上或者另外一个容器内的一个目录。后来新增了Volume生命周期的管理,以及Volume的驱动程序,虽然功能还非常有限。
Kubernetes卷具有明确的生命周期——与包裹它的Pod相同。因此,卷比Pod中运行的任何容器的存活周期都长,在容器重新启动时数据也会得到保留。当然,当一个Pod不再存在时,卷也将不存在。Kubernetes可以支持许多类型的卷,Pod也能同时使用任意数量的卷。
卷的核心是包含一些数据的目录,Pod中的容器可以访问该目录。特定的卷类型可以决定这个目录如何形成的,并能决定它支持何种介质,以及目录中存放什么内容。使用卷时,Pod声明中需要提供卷的类型(.spec.volumes字段)和卷挂载的位置(.spec.containers.volumeMounts字段)。容器中的进程能看到由它们的Docker镜像和卷组成的文件系统视图。Docker镜像位于文件系统层次结构的根部,并且任何Volume都挂载在镜像内的指定路径上。卷不能挂载到其他卷,也不能与其他卷有硬连接。Pod中的每个容器必须独立地指定每个卷的挂载位置。
容器存储的类型
容器架构使用到的三种存储:
(1)镜像存储
这个可以利用现有的共享存储,类似于虚拟化环境中虚拟机镜像的分发保护机制。容器镜像的优势在于其存储容量相较于完整的虚拟机镜像小了很多,因为不会复制操作系统代码。此外,容器镜像的运行在设计之初便是固定的,因此可以更高效地存储、共享。但也因此,容器镜像无法存储动态应用程序的数据。
(2)配置数据存储
这些配置数据用来管理容器,可以借助现有的存储来实现,主要是一些配置数据和日志记录等管理数据。
(3)应用数据存储
这些数据是重要的、临时的,也是最难存储下来的。相比虚拟机,容器的设计寿命更短,一旦容器销毁,所有的临时存储都会随之消失。因此,应用真正需要保存的数据,可以写入持久化的Volume数据卷。由于以微服务为主的容器应用多位分布式系统,容器可能在多个节点中动态地启动、停止、伸缩或者迁移。因此,当容器应用具有持久化的数据时,必须确保数据能被不同的节点所访问。另一方面,容器是面向应用的运行环境,数据通常要保存到文件系统中,即存储接口以文件形式更适应应用访问。
数据持久化存储数据量需要提前做好规划,对于容器迁移的支持也同样需要提供存储方面的支持。需要根据业务不同的需求,来提供不同的存储。etcd会存储平台的状态和配置信息,那么对性能、安全、稳定的要求就比较高。
平台中存储的应用场景
Kubernetes中对于存储的使用主要集中在以下几个方面:
服务的基本配置文件读取、密码密钥管理等;
服务的存储状态、数据存储等;
不同服务或应用程序间共享数据;
在Kubernetes中部署和运行的服务大致分为:
(1)无状态服务
Kubernetes使用ReplicateSet来保证一个服务的实例数量,如果说某个Pod实例由于某种原因挂掉或者崩溃,ReplicateSet会立刻用这个Pod的模版来替代它。由于是无状态的服务,新Pod与旧Pod一摸一样。此外Kubernetes通过Service(一个Service后面可以挂多个Pod)对外提供一个稳定的访问接口,实现服务的高可用。
(2)普通有状态服务
和无状态服务相比,它多了状态保存的需求。Kubernetes提供了以Volume和Persisettent Volume为基础的存储系统,可以实现服务状态的保存。
(3)有状态集群服务
和普通有状态服务相比,它多了集群管理的需求。要运行有状态集群服务要解决的问题有两个,一个是状态保存,另一个是集群管理。Kubernetes为此开发了StatefulSet,方便有状态集群服务在Kubernetes上部署和管理。
容器云存储设计的重要性
数据是一个企业重要的资产,如何利用好数据,可以实现企业的兴盛,如何保存好数据,则是保障企业兴盛的坚强后盾。因此,在平台建设前的规划阶段,必须做好充分的技术准备和项目调研,必须将数据的重要性提升到一个重要的层面来引起重视。
数据是企业的重要资产,保证数据不丢失,数据完整,数据一致,才能更好的开展业务。容器和虚拟机或物理机技术实现侧重不同,容器侧重无状态应用,要支持有状态应用,数据存储必须基于业务需求提前考虑和规划。
容器云是基础平台,涉及平台组件、镜像、应用、中间件等多个方面,每个方面都可能有不同的存储需求。要获得理想的性能和结果,需要全面的考虑每个方面,存储等作为基础设施资源,更是必不可少的部分。
容器是用来承载应用的,应用各个层次的数据具有潜在的价值,捕获并处理、存储、分析这些数据是获取价值的步骤。因此,应用数据的持久化是容器云平台支撑业务应用的重要的基础能力之一。建好基础,才能好地服务应用。
2、Kubernetes中几种常见的存储系统
从Kubernetes官方提供的数据看来,Kubernetes支持的Volume Plugin如下表所示:
Kubernetes已经提供了非常丰富的Volume和Persistent Volume插件,可以根据自身业务的特性,使用这些插件给容器提供存储服务。每一种Plugin的使用方法和注意事项参见:https://kuberne-tes.io/zh/docs/concepts/storage/
容器存储接口(Container Storage Interface,CSI)是一项跨行业标准倡议,旨在降低云原生存储开发工作的门槛,从而进一步确保兼容性水平。Kubernetes中CSI,将新分卷插件的安装流程简化至与安装Pod相当,并允许第三方存储供应商在无需接触核心Kubernetes代码库的前提下开发自己的解决方案。
3、持久化存储设计
前面提到了,数据是企业开展业务,进一步获取价值的源泉,是核心资产。重要的数据必须做持久化存储并按照监管/业务要求进行备份。容器持久化存储一般可以通过两种形式来实现:第一,是本地盘的形式,优势是简单易用,缺点是难以迁移共享以及伸缩;第二,是共享存储集群的形式,优势是数据共享,可以提供多种存储接口,可以弹性伸缩,缺点是架构稍显复杂。针对不同场景,持久化存储需要有不同的选择策略:
4 Kubernetes存储的设计与基本架构
4.1 Persistent Volume与Persistent Volume Claim概念介绍
一个运行中的容器,在缺省情况下,对文件系统的写入,都是发生在其分层文件系统的可写层的(copy-on-write)。当迁移的应用程序从开发到生产环境的时候,开发人员面临着巨大的挑战。当容器挂掉、崩溃或者运行结束时,任何与之相关的数据都会丢失。为了解决这个问题引发的数据丢失,我们需要将数据存储持久化,也可以称为Persistent Volume。
Kubernetes使用两种资源管理存储:
Persistent Volume(简称PV):由管理员添加的一个存储的描述,是一个全局资源,包含存储的类型,存储的大小和访问模式等。它的生命周期独立于Pod,例如当前使用它的Pod销毁时对PV没有影响。
Persistent Volume Claim(简称PVC):是Namespace里的资源,描述对PV的一个请求,请求信息包含存储大小、访问模式等。
Kubernetes中的Volume则是基于Docker进行扩展,使用 Docker Volume挂载宿主机上的文件目录到容器中。一般说来,Kubernetes中的Pod通过如下三种方式来访问存储:
(1)直接访问
该方式移植性较差,可扩展能力差,把Volume的基本信息完全暴露给用户,有严重的安全隐患,同时需要协调不同user对Volume的访问。
(2)静态provision
(3)动态provision
很明显,动态供应比静态供应灵活更多,而且这种方式还解耦了Kubernetes系统的计算层和存储层,更重要的是它给存储供应商提供了可插拔式的开发模型,存储供应商只需要根据这个模型开发相应的卷插件即可为Kubernetes提供存储服务。有三种方法实现:
In-tree Volume Plugin
Out-of-tree Provisioner
Out-of-tree CSI Driver
第一种,Kubernetes内部代码中实现了一些存储插件,用于支持一些主流网络存储。
第二种,如果有官方插件不能满足要求,存储供应商可以根据需要去定制或者优化存储插件并集成到Kubernetes系统。
第三种,是容器存储接口CSI,是Kubernetes对外开放的存储接口,实现这个接口即可集成到Kubernetes系统中。社区之前已经宣布将不再对in tree/out of tree继续开发,并将已有功能全部迁移到CSI上,所以对于存储供应商和使用者来说,第三种CSI方案更值得推荐。
一般来说,PV和PVC的生命周期分为5个阶段:
(1)Provisioning,即PV的创建,可以直接创建PV(静态方式),也可以使用Storage Class动态创建;
(2)Binding,将PV分配给PVC;
(3)Using,Pod通过PVC使用该Volume;
(4)Releasing,Pod释放Volume并删除PVC;
(5)Reclaiming,回收PV,可以保留PV以便下次使用,也可以直接从存储中删除。
根据这5个阶段,Volume的状态有以下4种:
Available:可用
Bound:已经分配给PVC
Release:PVC解绑但还未执行回收策略
Failed:发生错误
4.2 基础Kubernetes存储架构
Kubernetes存储在设计的时候遵循声明式(Declarative)架构。同时为了尽可能多地兼容各种存储平台,Kubernetes以in-tree plugin的形式来对接不同的存储系统,满足用户可以根据自己业务的需要使用这些插件给容器提供存储服务。同时兼容用户使用FlexVolume和CSI定制化插件。相比较于Docker Volume,支持的存储功能更加丰富和多样。
Kubernetes中mount一个PV的基本过程包括:
(1)用户通过API创建一个包含PVC的Pod;
(2)Scheduler把这个Pod分配到某个节点Node;
(3)节点Node上的Kublet开始等待Volume Manager准备Device;
(4)PV controller调用相应Volume Plugin(in-tree或者out-of-tree),创建PV,并在系统中与对应的PVC绑定;
(5)Attach/Detach controller或者Volume Manager通过Volume Plugin实现Device挂载(Attach);
(6)Volume Manager等待Device挂载完毕后,将卷挂载到节点指定目录;
(7)Node节点上的Kublet此时被告知Volume已经准备好后,开始启动Pod,通过Volume mapping将PV挂载到相应的容器中去。
Kubernetes存储架构设计图
觉得本文有用,请转发或点击“在看”,让更多同行看到
云架构师容器云平台存储、网络、监控的架构设计与优化在线辅导答疑
1. 容器平台存储概述
1.1 容器和 Kubernetes 存储概述
1.2 容器存储的类型
1.3 Kubernetes 平台中存储的应用场景
1.4 容器云存储设计的重要性
1.5 总结
2. Kubernetes 中几种常见的存储系统
3. 持久化存储设计
4. Kubernetes 存储的设计与基本架构
4.1 Persistent Volume与Persistent Volume Claim概念介绍
4.2 基础 Kubernetes 存储架构
5. 容器平台存储实践
5.1 某保险公司 OCP 容器平台存储设计
5.2 某基金公司测试环境 Kubernetes 容器平台存储设计
5.3 基于 CSI 开发的容器平台存储设计
6. 优化建议
此课程属于“2020 容器云职业技能大赛架构师岗课程系列”,是针对“2020 容器云职业技能大赛”(大赛详情请点击此处了解>>>)专门打造的精品课程,目前该系列有20个课程,识别二维码即可前往下载学习,还可以进行自测考试,完成所有课程及自测可获得岗位结业证书。
了解更多”2020年容器云职业技能大赛“信息:
下载 twt 社区客户端 APP
长按识别二维码即可下载
或到应用商店搜索“twt”
长按二维码关注公众号
*本公众号所发布内容仅代表作者观点,不代表社区立场